#ifndef ANN_NETWORK_HH
#define ANN_NETWORK_HH

#include "node.hh"
#include <initializer_list>
#include <vector>
#include <utility>
#include <memory>
#include <cassert>

namespace ann {
    class NodeCollection;

    typedef float(*activation_function_t)(int, float, float);

    class Network {
        struct impl_t;
        impl_t* impl;
        const activation_function_t activation;
        const size_t inputs, bias, outputs;


    public:
        Network (size_t inputs, size_t bias, size_t outputs,
                 activation_function_t activation,
                 NodeCollection const& nodes);
        ~Network ();

        void set_input (std::initializer_list<float> const& values);
        float get (size_t output) const;

        void step();
        void reset();

    private:
        void create_network (NodeCollection const&);
    };


    class NodeCollection {
        friend class Network;
        int id = 0;
        std::vector<std::pair<Node const*, size_t>> nodes;

    public:
        size_t size() const { return nodes.size(); }
        void add_node (Node const* n) { nodes.push_back(std::make_pair(n, id++)); }

    private:        
        size_t id_of (Node const* n) const {
            for (auto const& iter: nodes) {
                if (iter.first == n) return iter.second;
            }
            assert(false);
        }
    };


}

#endif

